// UhfReadApi.cpp: implementation of the UhfReadApi class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "UhfReader.h"
#include "UhfReadApi.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

UhfReadApi guhfapi;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

static unsigned char Uhf_CheckSum(unsigned char *uBuff, unsigned char uBuffLen)
{
	unsigned char i,uSum=0;
	for(i=0;i<uBuffLen;i++)
	{
		uSum = uSum + uBuff[i];
	}
	uSum = (~uSum) + 1;
	return uSum;
}


static int Byte2HexChar(BYTE *bData, int iLen, char *data)
{
	int ii = 0, jj = 0;
	for (ii = 0; ii < iLen; ii++, jj+=2)
	{
		sprintf(&data[jj], "%02x", bData[ii]);
	}
	data[jj] = 0;
	return 0;
}


p_ReadLabelCallback UhfReadApi::m_AutoReadLabel = NULL;

UhfReadApi::UhfReadApi()
{
	m_hComEvent = NULL;
}

UhfReadApi::~UhfReadApi()
{
	if (m_hComEvent)
	{
		CloseHandle(m_hComEvent);
		m_hComEvent = NULL;
	}
}

void OnCommBreak(LPVOID pSender,DWORD dwMask,COMSTAT stat)
{

	
}

#define SERIAL_BUFFER_SIZE 256
void SerialComCallback(void *pSender, void *data, DWORD nLen)
{
	UhfReadApi *pThis = (UhfReadApi*)pSender;
	pThis->ReadData((BYTE*)data, nLen);
}


/*
命令码: 01H
命令参数:1个字节BPS，取值:00H~08H，分别代表:
04H	9600bps
05H	19200bps
06H	38400bps
07H	57600bps
08H	115200bps
命令包: 『40H  03H  01H  BPS  CheckSum』
*/
int UhfReadApi::UhfSetBaudrate(unsigned char baud)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40;
	byteData[1] = 0x3;
	byteData[2] = CMD_SET_BAUD;
	byteData[3] = baud;
	byteData[4] = 0x40;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	UhfSendData(byteData, 5);
	return 0;
}

/*
命令码: 0BH
命令参数:1个字节BPS，取值:00H~FFH，分别代表:
0x00-0xFF(不可为0和FF，将返回错误)
命令包: 『40H  03H  0BH  BPS  CheckSum』
*/
int UhfReadApi::UhfSetTime(unsigned char baud)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40; 
	byteData[1] = 0x3;
	byteData[2] = CMD_SET_TIME;
	byteData[3] = baud;
	byteData[4] = 0x40;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	int ret = UhfSendData(byteData, 5);
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

/*
命令码: 0CH
命令参数:1个字节BPS，取值:00H~FFH，分别代表:
0x00-0xFF(不可为0和FF，将返回错误)
命令包: 『40H  03H  0CH  BPS  CheckSum』
*/
int UhfReadApi::UhfSetAddress(unsigned char baud)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40;
	byteData[1] = 0x3;
	byteData[2] = CMD_SET_ADDR;
	byteData[3] = baud;
	byteData[4] = 0x40;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	int ret = UhfSendData(byteData, 5);

	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

/*
命令码: 0DH
命令参数:1个字节BPS，取值:00H~98H，分别代表:
0x26
0x34
(后续根据客户需求添加，现只支持两种)
命令包: 『40H  03H  0DH  BPS  CheckSum』
*/
int UhfReadApi::UhfSetWg(unsigned char baud)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40;
	byteData[1] = 0x3;
	byteData[2] = CMD_SET_WG;
	byteData[3] = baud;
	byteData[4] = 0x40;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	int ret = UhfSendData(byteData, 5);

	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

/*
命令码: 0xFF
命令参数:1个字节BPS，取值:0x00、0x01、0x10、0x11，分别代表:

低字节控制蜂鸣器，
高字节控制LED灯
预留控制四个BUZ和四个LED灯
*/
int UhfReadApi::UhfSetBuzzerLed(unsigned char baud)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40;
	byteData[1] = 0x3;
	byteData[2] = CMD_SET_LED;
	byteData[3] = baud;
	byteData[4] = 0x40;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	int ret = UhfSendData(byteData, 5);

	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::UhfSetBuzzer(unsigned char baud)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40;
	byteData[1] = 0x3;
	byteData[2] = CMD_SET_BUZZ;
	byteData[3] = baud;
	byteData[4] = 0x40;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	int ret = UhfSendData(byteData, 5);

	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}


int UhfReadApi::UhfReadFactoryParameter(int Address)
{
	BYTE byteData[SERIAL_BUFFER_SIZE];
	byteData[0] = 0x40;
	byteData[1] = 0x2;
	byteData[2] = CMD_SET_FACTORY;
	byteData[3] = Uhf_CheckSum(byteData, 3);
	int ret = UhfSendData(byteData, 4);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::Rs232_OpenPort(int port, int baud)
{

	if (!m_hComEvent)
		m_hComEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	m_serial.SetReceiveFunc(SerialComCallback, this);
	m_serial.SetBreakHandleFunc(OnCommBreak);
	//	m_serial.Open(iPort, LsComm::CComPort::ManualReceiveByConst, iBaud);
	m_serial.Open(port, LsComm::CComPort::AutoReceiveBySignal, baud);
	if (m_serial.GetSerialPort())
		return 1;
	return 0;
}

int UhfReadApi::Rs232_ClosePort()
{
	m_serial.Close();
	return 0;
}


/*
命令码: 01H
命令参数:1个字节BPS，取值:00H~08H，分别代表:
04H	9600bps
05H	19200bps
06H	38400bps
07H	57600bps
08H	115200bps
命令包: 『40H  03H  01H  BPS  CheckSum』
*/


/*
命令码: 0BH
命令参数:1个字节BPS，取值:00H~FFH，分别代表:
0x00-0xFF(不可为0和FF，将返回错误)
命令包: 『40H  03H  0BH  BPS  CheckSum』
*/


/*
命令码: 0CH
命令参数:1个字节BPS，取值:00H~FFH，分别代表:
0x00-0xFF(不可为0和FF，将返回错误)
命令包: 『40H  03H  0CH  BPS  CheckSum』
*/


/*
命令码: 0DH
命令参数:1个字节BPS，取值:00H~98H，分别代表:
0x26
0x34
(后续根据客户需求添加，现只支持两种)
命令包: 『40H  03H  0DH  BPS  CheckSum』
*/

/*
命令码: 0xFF
命令参数:1个字节BPS，取值:0x00、0x01、0x10、0x11，分别代表:

低字节控制蜂鸣器，
高字节控制LED灯
预留控制四个BUZ和四个LED灯

命令包: 『40H  03H  FFH  BPS  CheckSum』
*/

/*
正确：命令包: 『F0H  02H 命令码 CheckSum』
错误：命令包: 『F4H  03H 命令码 错误码（可能为出错后读取FLASH存储值，即设置错误后，值为多少）CheckSum』
*/

void UHFReadTag(void *pParent, BYTE *data, int dwLen)
{
	UhfReadApi *pThis = (UhfReadApi *)pParent;
	//	pThis->EPCC1G2ReadTag(data, dwLen);
	pThis->UhfReadTag(data, dwLen);
	return ;
}

int UhfReadApi::UhfSendData(BYTE *bData, int iLen)
{
	if (!m_serial.GetSerialPort())
		return 0;

	ResetEvent(m_hComEvent);

	int ret = m_serial.Output(bData, iLen);
	if (WAIT_TIMEOUT == WaitForSingleObject(m_hComEvent, 2000))
	{
		ret = 0;
	}
	else
	{
		return 1;
	}
	return ret;
}

int UhfReadApi::ReadData(BYTE *bData, int nLen)
{
	memcpy(m_bData, bData, nLen);
	m_iLen = nLen;
	if ((m_bData[0] == 0xF0 || m_bData[0] == 0xF4) && nLen >= m_bData[1] + 2)
	{
		SetEvent(m_hComEvent);
		return m_bData[1];
	}
	return 0;
}


int UhfReadApi::UhfAutoReadLabelID(BYTE mem, int ptr, BYTE len, BYTE *mask, unsigned char *IDBuffer, int *nCounter, p_ReadLabelCallback ReadLabelCallback, void *Parent)
{
//	m_IsAutoReadLabel = TRUE;

//	m_pEpccParent = Parent;

	if (UhfSetAntenna(1))
	{
		return 1;
	}

	BYTE byteData[1024] = {0};
	int iLen = 6;
	byteData[0] = 0x40;
	byteData[2] = CMD_BEGIN_LIST_LABEL;
	*(USHORT*)&byteData[3] = mem;
	*(USHORT*)&byteData[5] = ptr;

	m_AutoReadLabel = ReadLabelCallback;
	
	int maskLen = len/8;
	if (0 == len % 8)
	{
		iLen = 8 + maskLen;
		if (len != 0)
			memcpy(&byteData[7], mask, maskLen);
		byteData[1] = 6 + maskLen;
		byteData[7 + maskLen] = Uhf_CheckSum(byteData, 7 + maskLen);
	}
	else
	{
		iLen = 9 + maskLen;
		if (len != 0)
		memcpy(&byteData[7], mask, maskLen+1);
		byteData[1] = 7 + maskLen;
		byteData[8 + maskLen] = Uhf_CheckSum(byteData, 8 + maskLen);
	}
	
	ResetEvent(m_hComEvent);
	
	if (UhfSendData(byteData, iLen))
	{
		(*ReadLabelCallback)(Parent, m_bData, m_iLen);
		Sleep(500);
		return 0;
	}
	else
	{
		Sleep(500);
	}

	
	return 1;
}

int UhfReadApi::UhfReadTag(BYTE *data, int dwLen)
{
	BYTE bData[256];
	int m_epcLen = 0;
	memcpy(&bData[m_epcLen], data, dwLen);

	m_epcLen += dwLen;

	CString str_temp, str;
	char temp[64];
	int ID_len_temp, ID_len;
	while (m_epcLen > 2)
	{
		if (bData[0] == 0xF0)
		{
			if ( !(m_epcLen >= bData[1] + 2) )
				return 0;
			BYTE bEPC[40];
			int iEPCLen = 0;

			if (bData[1] + 2 > m_epcLen)
			{
				return 0;
			}

			if (bData[bData[1] + 1] != Uhf_CheckSum(bData, bData[1] + 1))
			{
				//校验错误
				m_epcLen = 0;
				continue;
			}

			if (bData[2] != 0xEE)	//命令错误
			{
				m_epcLen = 0;
				continue;
			}

			BYTE tmpbuff[256];
			int dataLen = bData[1] - 2;
			int epcDataLen = bData[3];

			memcpy(tmpbuff, &bData[4], dataLen);

//			CListCtrl *pListCG = (CListCtrl *)pThis->GetDlgItem(IDC_LIST_CG);
//			CListCtrl *pListCG = (CListCtrl *)GetDlgItem(IDC_LIST_CG);

//			int count = pListCG->GetItemCount();
//			int k = count;
			int k = 0;

			int kk = 0, npLen = 1, nCounter = epcDataLen;
			for (kk = 0; kk < epcDataLen; kk++)
			{
				char data[256] = {0};
				int nLen = tmpbuff[npLen - 1];
				Byte2HexChar(&tmpbuff[npLen], nLen*2, data);

				memcpy(bEPC, &tmpbuff[npLen], nLen*2);

				npLen += nLen*2 + 1;

				iEPCLen = nLen*2;

				str = data;
				ID_len = nLen * 2;

				//////////////////////////////////////////////////////////////////////////
				int i = kk;
				
				int j = 0;
				
#if 0
				for(j=0;j<k;j++)
				{
					m_List6cID.GetItemText(j, 4, temp, 3);
					
					ID_len_temp=((BYTE)strtol(temp, NULL, 16))*2;
					if (ID_len == ID_len_temp)
					{
						m_List6cID.GetItemText(j, 1, temp, 64);
						str_temp=temp;
						if(str == str_temp) break;
					}
				}
				if(j == k)
				{
					m_List6cID.InsertItem(k,itoa(k+1,temp,10));
					m_List6cID.SetItemText(k,1,str);
					m_List6cID.SetItemText(k,2,"1");
					str_temp.Format("%02X",EPCC1G2_IDBuffer[i][0]);
					str_temp.Format("%d", iEPCLen / 2);
					m_List6cID.SetItemText(k,4,str_temp);
					m_List6cID.EnsureVisible(k,TRUE);
					k++;
					
					m_tag6C.m_iIndex = m_listTag.size();
					memcpy(m_tag6C.m_bTagID, bEPC, iEPCLen);
					m_tag6C.m_iTagLen = iEPCLen;
					m_tag6C.m_strTagID = str;
					m_listTag.push_back(m_tag6C);
					/*
					m_cbRWTagID.AddString(str);
					m_cbKillTagID.AddString(str);
					m_cbProtectTagID.AddString(str);
					m_cbLockTagIDUser.AddString(str);
					m_cbAlarmTagID.AddString(str);
					m_cbReadProtectTagID.AddString(str);
					
					if (k == 1)
						SetDlgItemText(IDC_EDIT_UNLOCK_READ, str);
					
					m_cbRWTagID.SetCurSel(0);
					m_cbKillTagID.SetCurSel(0);
					m_cbProtectTagID.SetCurSel(0);
					m_cbLockTagIDUser.SetCurSel(0);
					m_cbAlarmTagID.SetCurSel(0);
					m_cbReadProtectTagID.SetCurSel(0);
					*/
				}
				else
				{
					str_temp=m_List6cID.GetItemText(j,2);
					m_List6cID.SetItemText(j, 2, itoa(atoi(str_temp)+1, temp, 10));
				}
#endif
			}

			m_epcLen = m_epcLen - bData[1] - 2;

			epcDataLen = bData[1] + 2;

			if (epcDataLen + m_epcLen > 512)
			{
				m_epcLen = 0;
				break;
			}
			else
				memcpy(bData, &bData[epcDataLen], m_epcLen);
		}
		else
		{
			int ii = 0;
			while (m_epcLen > 0)
			{
				if (bData[ii] != 0xF0)
				{
					ii++;
					m_epcLen--;
				}
				else
				{
					memcpy(bData, &bData[ii], m_epcLen);
					break;
				}
			}
//			m_epcLen = 0;
		}
	}
	return 0;
}

int UhfReadApi::UhfStopAutoReadEPC()
{
	BYTE byteData[SERIAL_BUFFER_SIZE] = {0};
	int iLen = 4;
	byteData[0] = 0x40;
	byteData[2] = 0xE0;	//CMD_AUTO_MODE;
	
	//	m_AutoReadLabel = NULL;
	
	byteData[1] = 2;
	byteData[3] = Uhf_CheckSum(byteData, 3);
	
	ResetEvent(m_hComEvent);

#if 0
	int ret = UhfSendData(byteData, 4);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
#else
	int ret = 0;
#endif
	return ret;
}

int UhfReadApi::UhfSetAntenna(int Antenna)
{
	BYTE byteData[256] = {0};
	int iLen = 5;
	byteData[0] = 0x40;
	byteData[2] = CMD_SELECT_AERIAL;
	byteData[3] = Antenna;
	
	byteData[1] = 3;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	
	int ret = UhfSendData(byteData, 5);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::UhfReadBasicParam(ReaderBasicParam *pParam)
{
	BYTE byteData[256] = {0};
	int iLen = 4;
	byteData[0] = 0x40;
	byteData[2] = CMD_GET_BASIC_PARAM;
	
	int tagLen = sizeof(ReaderBasicParam);
	byteData[1] = 2;
	byteData[3] = Uhf_CheckSum(byteData, 3);

	int ret = UhfSendData(byteData, 4);

	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			memcpy(pParam, &m_bData[3], 32);
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::UhfWriteBasicParam(ReaderBasicParam *pParam)
{
	BYTE byteData[256] = {0};
	int iLen = 4;
	byteData[0] = 0x40;
	byteData[2] = CMD_SET_BASIC_PARAM;
	byteData[3] = 0;
	
	int tagLen = sizeof(ReaderBasicParam);
	byteData[1] = 2+tagLen;
	memcpy(&byteData[3], pParam, tagLen);
	
	iLen = 4+tagLen;
	
	byteData[3+tagLen] = Uhf_CheckSum(byteData, 3+tagLen);

	int ret = UhfSendData(byteData, 4+tagLen);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::UhfGetFrequencyRange(BYTE *Frequency)
{
	BYTE byteData[SERIAL_BUFFER_SIZE] = {0};
	int iLen = 4;
	byteData[0] = 0x40;
	byteData[2] = CMD_GETFREQ;
	byteData[3] = 0;
	
	byteData[1] = 2;
	byteData[3] = Uhf_CheckSum(byteData, 3);

	int ret = UhfSendData(byteData, 4);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			*Frequency = m_bData[3];
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::UhfSetWorkMode(unsigned char mode)
{
	BYTE byteData[SERIAL_BUFFER_SIZE] = {0};
	int iLen = 4;
	byteData[0] = 0x40;
	byteData[2] = CMD_SET_WORKMODE;
	byteData[3] = mode;
	
	byteData[1] = 3;
	byteData[4] = Uhf_CheckSum(byteData, 4);
	
	int ret = UhfSendData(byteData, 5);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
//			*Frequency = m_bData[3];
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}

int UhfReadApi::UhfGetConfig(unsigned char *config)
{
	BYTE byteData[SERIAL_BUFFER_SIZE] = {0};
	int iLen = 4;
	byteData[0] = 0x40;
	byteData[2] = CMD_GET_CONFIG;
	byteData[3] = 0;
	
	byteData[1] = 2;
	byteData[3] = Uhf_CheckSum(byteData, 3);
	
	int ret = UhfSendData(byteData, 4);
	
	if (ret)
	{
		if (m_bData[0]== 0xF0)
		{
			//OK
			memcpy(config, &m_bData[3], 5);
			return 0;
		}
		else
		{
			//Fail
			ret = 1;
		}
	}
	else
	{
		// Fail
		ret = 1;
	}
	return ret;
}
